Thread: VERY simple problem, can't figure it out for the life of me. :[

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    11

    VERY simple problem, can't figure it out for the life of me. :[

    Ok, so all i'm trying to do is make a linked list of dictionary entries, and for some reason allocating the second or third linked list kills my program. I have no idea why. Here is the code:

    header file:
    Code:
    #ifndef WORDSTAT_H
    #define WORDSTAT_H
    
    #define MAX_LINE 1024
    /*define structure and functions*/
    
    #define TS "?,.;\"': \n\t!()-<>[]{}1234567890"
    
    
    struct wordEntry{
        char *word;
        int count;
        struct wordEntry *next;
    };
    
    typedef struct wordEntry entry;
    
    #endif
    source file:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "template_wordstat.h"
    
    void append(entry * beginning, char * nextWord);
    
    int main(int argc, char* argv[])
    {
        FILE* fp;
        char line[MAX_LINE];
        int i = 0;
        char *nextWord;
        entry *start = NULL;
    
    
        /* Checks for correct usage and handles arguments accordingly */
    
        if (argc != 2) {
            fprintf(stderr, "Error: wrong number of parameters.\n");
            return -1;
        }
    
    	if (strcmp(argv[1],"-h") == 0) {
            	printf("Usage: wordstat FILE_NAME\n");
            	return 0;
       	}
    
        if ((fp=fopen(argv[1],"r")) == NULL) {
            fprintf(stderr, "Error: cannot open file %s.\n", argv[1]);
            return -2;
        }
    
        while (! feof(fp)) {
    
            /* reads one line at a time */
    
                if (fgets(line, MAX_LINE, fp) == NULL)
                        break;
                if (line[0] == '\n')    /* empty line */
                        continue;
    
            /* extract words from the line and handle the words	*/
    
            nextWord = strtok (line, TS);
    
            /* if the first token is empty, then there are no words */
    
            if(nextWord == NULL){
                fprintf(stderr, "File contains no words.\n");
                return -2;
            }
    
            /* go through each word and build linked list with entries*/
    
            while(nextWord != NULL){
    
                append(start, nextWord);
                printf("%s\n", nextWord);
                nextWord = strtok (NULL, TS);
            }
        }
    
    	/*	sorting and printing */
    
    	fclose(fp);
    
        	return 0;
    }
    
    void append(entry * beginning, char * nextWord) {
        entry *temp,*marker;
    
        temp = (entry *)malloc(sizeof(entry));
        strcpy(temp->word, nextWord);
        temp -> count = 0;
        temp -> next = NULL;
    
        marker = beginning;
    
        /* If the very first node is empty */
        if (beginning == NULL) {
            beginning = temp;
            beginning -> next = NULL;
        }
        else {
            while(marker -> next != NULL)
                marker = marker -> next;
    
           marker -> next = temp;
        }
     }
    any help would be appreciated. I REALLy don't seem to get pointers :[

    EDIT: I revised the code, it still doesn't work.
    Last edited by rasheemo; 09-27-2009 at 11:48 AM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You aren't actually making a linked list. You're just setting head to current, and next to NULL.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    hmm, maybe i dont even know what a proper linked list is.

    i'm making head the first member of the linked list, then allocating memory for curent, which i stick to the end of the list, in the first case that would be head -> next, right?

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So, when you malloc a new node, do you plan to set head->next (or anything, for that matter, since head->next will only be right for item #2) to point to the new entry?

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    i set curr to head and then i traverse until i get to a null, and then i malloc. isn't that right?

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by rasheemo View Post
    i set curr to head and then i traverse until i get to a null, and then i malloc. isn't that right?
    No. You have to hook that freshly minted object into your list.

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    ok, so don't i have to first find the last node that has a NULL 'next'? and once i get there i set the next of that node to curr and then malloc? How do i define a new node without using a variable name?

    thanks so much for the help btw

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That depends if you want to prepend, or append.
    Code:
    p1 = p2 = malloc a node
    while not done
        get some word or whatever you're doing
        malloc a new node
        stick your word in it
        prepend it to your list | append it to your list
    To prepend, you only need the head node.
    Code:
    newnode->next = head;
    head = newnode;
    To append, you need a pointer that points to the end of the list.
    Code:
    while p and p->next
        p = p->next
    if p
        p->next = new node

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by rasheemo View Post
    ok, so don't i have to first find the last node that has a NULL 'next'? and once i get there i set the next of that node to curr and then malloc?
    That's (almost) exactly what you need to do. (You need to malloc curr first, then set the next of that node to curr.) Since you do none of this in your code, I would suggest you try it.

  10. #10
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    ok, i can't figure this out at all. This is what i THINK is happening with my program:

    Code:
    curr = head;
    I assign curr to the very first node in the linked list.

    Code:
    while(curr){
                    printf("traversing!");
                    curr = curr->next;
                }
    I set curr to the next one linked to it until i get to the last node (NULL).

    Code:
    if ((curr = (struct wordEntry*)malloc(sizeof(entry))) == NULL)
    I allocate space for the curr, which is located at the null entry.

    then i assign all the variables of the last node, and start all over.

    Why isn't this working? :[

    EDIT: i'm revising my code, don't bother helping me out just yet.
    EDIT 2: OK I update the parent post with my latest revised code. It still doesn't work even though it really seems like it should!

    THANKS IN ADVANCE!
    Last edited by rasheemo; 09-27-2009 at 11:49 AM.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    What value are you passing in as the first parameter to 'Append' every time?
    That's the problem.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    i'm passing the first node of the list, aren't I?

    It's null the first time, so 'append' sets it equal to temp.
    the second time around, beginnging/start has a value right? am i passing the pointers properly?

    this is so frustrating :[

    EDIT: Btw i'm not allowed to use global variables, so i'm passing the starting node each time.
    Last edited by rasheemo; 09-27-2009 at 12:43 PM.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by rasheemo View Post
    i'm passing the first node of the list, aren't I?

    It's null the first time, so 'append' sets it equal to temp.
    the second time around, beginnging/start has a value right? am i passing the pointers properly?

    this is so frustrating :[
    Whoops! Pass by value pitfall!

    If you reassign a passed parameter in a function, that assignment does not apply to the original source. Consider:
    Code:
    struct whatever *ptr = NULL;
    myfunc(ptr);
    What that actually does is pass the value of the pointer, ie, the address assigned to it. Which is NULL. So what you are really doing is this:
    Code:
    myfunct(NULL);
    Inside myfunc, the argument is assigned to a local stack variable of the appropriate type. If you reassign it:
    Code:
    param = malloc(whatever);
    what you have reassigned is that stack variable, not the variable which supplied the value. Since you malloc'd it onto the heap, that is a memory leak.

    You need to use the return value of your function:
    Code:
    struct whatever *ptr = myfunc();
    Which means changing it's type from void to entry*.

    Get it? Someone should have explained this to you in post #2.
    Last edited by MK27; 09-27-2009 at 12:48 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Registered User
    Join Date
    Sep 2009
    Posts
    11
    so can't i just send '&start' to pass the pointer itself? but the compiler won't allow that for some reason.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You can, if you change beginning to be a pointer to a pointer to entry, and modify the implementation of the append function accordingly.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  2. Replies: 5
    Last Post: 12-03-2003, 05:47 PM
  3. Im a Newbie with a graphics design problem for my simple game
    By Robert_Ingleby in forum C++ Programming
    Replies: 1
    Last Post: 11-23-2001, 06:41 PM
  4. Simple boolean problem
    By larry in forum C++ Programming
    Replies: 9
    Last Post: 10-13-2001, 08:49 AM
  5. A Simple (?) Problem
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 10-12-2001, 04:28 AM